package pers.mtx.myapplication;

import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zlylib.fileselectorlib.FileSelector;
import com.zlylib.fileselectorlib.bean.EssFile;
import com.zlylib.fileselectorlib.utils.Const;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import pers.mtx.myapplication.db.MyDatabaseHelper;
import pers.mtx.myapplication.model.Chatmodel.get.SucChatRecord;
import pers.mtx.myapplication.model.Chatmodel.get.msg.FileMsg;
import pers.mtx.myapplication.model.Chatmodel.get.msg.FileMsgVo;
import pers.mtx.myapplication.model.Chatmodel.get.msg.TextMsgVo;
import pers.mtx.myapplication.model.Chatmodel.put.LongConnectionChatDTO;
import pers.mtx.myapplication.model.Data;
import pers.mtx.myapplication.model.ResUserData;
import pers.mtx.myapplication.service.WebSocketService;
import pers.mtx.myapplication.util.FileReadUtils;
import pers.mtx.myapplication.util.SendChatUtil;
import pers.mtx.myapplication.util.WpsModel;

public class ChatActivity extends AppCompatActivity {
    private WebSocketService webSocketService;
    private String conversinerId = "";
    private String conversinerName = "";
    private static String TAG = "ChatActivity";
    private MyDatabaseHelper dbHelper;
    private SQLiteDatabase db;
    private ArrayList<MsgData> msgDataList = new ArrayList<>();
    private SendBroadcastReceiver msgReceiver;
    private ReceiveBroadcastReceiver recmsgReceiver;
    private final OkHttpClient client = new OkHttpClient();
    ObjectMapper mapper = new ObjectMapper();


    @BindView(R.id.name)
    TextView nameView;
    @BindView(R.id.chat)
    LinearLayout linearLayout;
    @BindView(R.id.content)
    EditText contentText;

    private class SendBroadcastReceiver extends BroadcastReceiver {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, intent.toString());
            //这里是要在Activity活动里执行的代码
            Serializable ChatEntity = intent.getSerializableExtra("chat");
            LongConnectionChatDTO chatDTO = (LongConnectionChatDTO) intent.getSerializableExtra("chatDTO");
            MsgData msgData = new MsgData();
            @SuppressLint("SimpleDateFormat") SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            switch (intent.getIntExtra("type", 0)) {
                case 1:
                    SucChatRecord chat = (SucChatRecord) ChatEntity;
                    try {
                        msgData.setMsg_type(1).setMsg(chat.getMessage()).setSender_id(chat.getSenderid()).setMsg_id(chat.getMsgid()).setSend_time(sdf.parse(chat.getTime()));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    break;
                case 5:
                    FileMsgVo chatF = (FileMsgVo) ChatEntity;
                    try {

                        msgData.setMsg_type(5).setMsg(chatF.getUrl() + "_mtx_" + chatF.getFileName()).setSender_id(chatF.getSenderId()).setMsg_id(chatF.getMsgId()).setSend_time(sdf.parse(chatF.getTime()));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    break;
            }
            msgDataList.add(msgData);
            linearLayout.removeAllViews();
            refleshByList();
        }
    }

    private class ReceiveBroadcastReceiver extends BroadcastReceiver {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onReceive(Context context, Intent intent) {

            Log.i(TAG, intent.toString());

            MsgData msgData = new MsgData();
            @SuppressLint("SimpleDateFormat") SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            switch (intent.getIntExtra("type",0)){
                case 1:
                    TextMsgVo textVo = (TextMsgVo) intent.getSerializableExtra("chat");
                    try {
                        msgData.setMsg(textVo.getMessage()).setSender_id(textVo.getSenderId()).setSend_time(sdf.parse(textVo.getTime())).setMsg_type(1).setMsg_id(textVo.getMsgId());
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    break;
                case 5:
                    FileMsgVo fileMsg = (FileMsgVo) intent.getSerializableExtra("chat");
                    try {
                        msgData.setMsg_type(5).setMsg(fileMsg.getUrl() + "_mtx_" + fileMsg.getFileName()).setSender_id(fileMsg.getSenderId()).setSend_time(sdf.parse(fileMsg.getTime())).setMsg_id(fileMsg.getMsgId());
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    break;
            }


            msgDataList.add(msgData);
            linearLayout.removeAllViews();
            refleshByList();
        }
    }


    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chat_activity);
        ButterKnife.bind(this);
        Intent intent = new Intent(ChatActivity.this, WebSocketService.class);
        bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
        conversinerId = getIntent().getStringExtra("conversinerId");
        dbHelper = new MyDatabaseHelper(ChatActivity.this, 5);
        //这次是read，以前都是write
        db = dbHelper.getReadableDatabase();
        conversinerName = getIntent().getStringExtra("name");
        nameView.setText(conversinerName);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("sendSuc.mtx." + conversinerId);
        msgReceiver = new SendBroadcastReceiver();
        registerReceiver(msgReceiver, intentFilter);

        IntentFilter intentFilterReceive = new IntentFilter();
        intentFilterReceive.addAction("receiveSuc.mtx." + conversinerId);
        recmsgReceiver = new ReceiveBroadcastReceiver();
        registerReceiver(recmsgReceiver, intentFilterReceive);

        setUpDataByDB();
    }

    @OnClick(R.id.sendTxt)
    public void send(View v) {
        String chatId = UUID.randomUUID().toString();
        LongConnectionChatDTO chatDTO = new LongConnectionChatDTO(chatId, conversinerId, contentText.getText().toString(), LongConnectionChatDTO.TEXT);
        SendChatUtil.getInstanse().getMap().put(chatId, chatDTO);
        webSocketService.sendMessage(chatDTO);
    }

    @OnClick(R.id.sendFile)
    public void sendFile(View v) {
        FileSelector.from(this)
                // .onlyShowFolder()  //只显示文件夹
                //.onlySelectFolder()  //只能选择文件夹
                // .isSingle() // 只能选择一个
                .setMaxCount(5) //设置最大选择数
//                .setFileTypes("png", "doc", "apk", "mp3", "gif", "txt", "jpg", "zip") //设置文件类型
                .setSortType(FileSelector.BY_NAME_ASC) //设置名字排序
                //.setSortType(FileSelector.BY_TIME_ASC) //设置时间排序
                //.setSortType(FileSelector.BY_SIZE_DESC) //设置大小排序
                //.setSortType(FileSelector.BY_EXTENSION_DESC) //设置类型排序
                .requestCode(1) //设置返回码
                .setTargetPath("/storage/emulated/0/Android/data/") //设置默认目录
                .start();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1) {
            if (data != null) {
                ArrayList<String> essFileList = data.getStringArrayListExtra(Const.EXTRA_RESULT_SELECTION);
                StringBuilder builder = new StringBuilder();
                for (String file : essFileList) {
                    Log.i(TAG, file);
                    byte[] byteStream = FileReadUtils.getByteStream(file);
                    String chatId = UUID.randomUUID().toString();
                    String[] split = file.split("/");
                    FileMsg fileMsg = new FileMsg(split[split.length - 1], byteStream);
                    LongConnectionChatDTO chatDTO = new LongConnectionChatDTO(chatId, conversinerId, fileMsg, LongConnectionChatDTO.FILE);
                    SendChatUtil.getInstanse().getMap().put(chatId, chatDTO);
                    webSocketService.sendMessage(chatDTO);
                    Log.i(TAG, String.valueOf(byteStream.length));
                }
//                FileReadUtils.getByteStream(builder.toString());

            }
        }else if (requestCode==2){
//            String stringExtra = data.getStringExtra(Const.EXTRA_RESULT_SELECTION);
            String absolutePath = ((ArrayList<EssFile>) data.getExtras().getSerializable(Const.EXTRA_RESULT_SELECTION)).get(0).getAbsolutePath();
            try {
                openFile(absolutePath);
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
    }

    boolean openFile(String path) throws URISyntaxException {
        Intent intent = new Intent();
        Bundle bundle = new Bundle();
        bundle.putString(WpsModel.OPEN_MODE, WpsModel.OpenMode.NORMAL); // 打开模式
        bundle.putBoolean(WpsModel.SEND_CLOSE_BROAD, false); // 关闭时是否发送广播
        bundle.putBoolean(WpsModel.SEND_SAVE_BROAD, false);
        bundle.putString(WpsModel.THIRD_PACKAGE, getPackageName()); // 第三方应用的包名，用于对改应用合法性的验证
        bundle.putBoolean(WpsModel.CLEAR_TRACE, true);// 清除打开记录
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(android.content.Intent.ACTION_VIEW);
        intent.setClassName(WpsModel.PackageName.NORMAL, WpsModel.ClassName.NORMAL);
        File file = new File(path);

        if (!file.exists()) {
            System.out.println("文件为空或者不存在");
            return false;
        }

        Uri uri = FileProvider.getUriForFile(this,"pers.mtx.myapplication",file);
        intent.setData(uri);
        intent.putExtras(bundle);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        try {
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
            System.out.println("打开wps异常："+e.toString());
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    LinearLayout data = (LinearLayout) msg.obj;
                    linearLayout.addView(data);
                    break;
            }
        }
    };

    @SuppressLint("SetTextI18n")
    @RequiresApi(api = Build.VERSION_CODES.N)
    private void setUpDataByDB() {
        msgDataList.clear();
        @SuppressLint("Recycle") Cursor cursor = db.rawQuery("select * from chat_record where sender_id = ? or receiver_id = ?", new String[]{conversinerId, conversinerId});
        if (cursor.moveToFirst()) {
            do {
                //通过列名找到数据
                @SuppressLint("Range") String msg = cursor.getString(cursor.getColumnIndex("message"));
                @SuppressLint("Range") Integer msg_type = cursor.getInt(cursor.getColumnIndex("msg_type"));
                @SuppressLint("Range") String send_time = cursor.getString(cursor.getColumnIndex("send_time"));
                @SuppressLint("Range") String msg_id = cursor.getString(cursor.getColumnIndex("msg_id"));
                @SuppressLint("Range") String sender_id = cursor.getString(cursor.getColumnIndex("sender_id"));
                MsgData msgData = new MsgData();
                msgData.setMsg(msg).setMsg_id(msg_id).setMsg_type(msg_type).setSend_time(new Date(send_time)).setSender_id(sender_id);
                msgDataList.add(msgData);
            } while (cursor.moveToNext());
        }
        refleshByList();
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void refleshByList() {
        msgDataList.stream().sorted((o1, o2) -> {
            if (o1.getSend_time().after(o2.getSend_time())) {
                return 1;
            } else if (o2.getSend_time().after(o1.getSend_time())) {
                return -1;
            } else {
                return 0;
            }
        });
        for (MsgData item :
                msgDataList) {
            Log.i(TAG, "setUpDataByDB: " + item.getSend_time());
            TextView userText = new TextView(ChatActivity.this);
            TextView contentText = new TextView(ChatActivity.this);
            contentText.setTextColor(Color.BLACK);
            userText.setTextColor(Color.BLACK);
            if (item.getSender_id().equals(conversinerId)) {
                userText.setText(conversinerName + ":");
                userText.setGravity(Gravity.RIGHT);
                contentText.setGravity(Gravity.RIGHT);
            } else {
                userText.setText("我:");
            }

            String[] split = item.msg.split("_mtx_");
            LinearLayout linearLayout = new LinearLayout(ChatActivity.this);
            linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            if (item.getMsg_type()==5){
                contentText.setText(split[1]);

                contentText.setTextColor(Color.BLUE);
                linearLayout.setOnClickListener(v -> {
                    Log.i(TAG, "refleshByList: wwwwwwwwww");
                    try {
                        getFile(split[0],split[1]);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }else {
                contentText.setText(item.msg);
            }
            linearLayout.setGravity(View.FOCUS_RIGHT);
            linearLayout.setOrientation(LinearLayout.VERTICAL);
            linearLayout.addView(userText);
            linearLayout.addView(contentText);

            Message message = new Message();
            message.what = 1;
            message.obj = linearLayout;
            handler.sendMessage(message);
        }
    }

    class MsgData {
        private String msg;
        private String sender_id;
        private Integer msg_type;
        private Date send_time;
        private String msg_id;

        public MsgData setMsg(String msg) {
            this.msg = msg;
            return this;
        }

        public MsgData setMsg_type(Integer msg_type) {
            this.msg_type = msg_type;
            return this;
        }

        public MsgData setSend_time(Date send_time) {
            this.send_time = send_time;
            return this;
        }

        public MsgData setMsg_id(String msg_id) {
            this.msg_id = msg_id;
            return this;
        }

        public String getSender_id() {
            return sender_id;
        }

        public MsgData setSender_id(String sender_id) {
            this.sender_id = sender_id;
            return this;
        }

        public String getMsg() {
            return msg;
        }

        public Integer getMsg_type() {
            return msg_type;
        }

        public Date getSend_time() {
            return send_time;
        }

        public String getMsg_id() {
            return msg_id;
        }
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder iBinder) {
            WebSocketService.WebSocketBinder binder = (WebSocketService.WebSocketBinder) iBinder;
            webSocketService = binder.getService();
            Log.d("ChatActivity", "onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("ChatActivity", "onServiceDisconnected");
        }
    };


    public void getFile(String url,String fileName) throws Exception {
        Request request = new Request.Builder()
                .url("http://192.168.1.109:8080/chat/File/download/" + url)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try (ResponseBody responseBody = response.body()) {
                    if (!response.isSuccessful())
                        throw new IOException("Unexpected code " + response);
                    FileOutputStream outputStream;
                    File file = new File(ChatActivity.this.getFilesDir(), fileName);
                    try{
                        outputStream = openFileOutput(fileName,Context.MODE_PRIVATE);
                        assert responseBody != null;
                        outputStream.write(responseBody.bytes());
                        outputStream.close();
                        openFile(file.getAbsolutePath());
                        runOnUiThread(() -> {
                            Toast.makeText(getApplicationContext(), "文件保存成功", Toast.LENGTH_SHORT).show();
                            FileSelector.from(ChatActivity.this)
                                    .setSortType(FileSelector.BY_NAME_ASC) //设置名字排序
//                                    .setMaxCount(2) //设置最大选择数
                                    .isSingle()
                                    .setTargetPath(ChatActivity.this.getFilesDir().getPath())
                                    .requestCode(2) //设置返回码
                                    .start();
                        });
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                }
            }
        });
    }

}
